﻿using Caliburn.Micro;
using Microsoft.Win32;
using SD.Common;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using SD.Infrastructure.WPF.Interfaces;
using SD.Infrastructure.WPF.Models;
using SD.IOC.Core.Mediators;
using SD.Toolkits.Excel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using SlamDunk.MES.IAppService.DTOs.Outputs.QualityContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation;
using SlamDunk.MES.Presentation.Maps;
using SlamDunk.MES.Presentation.Models.ExportModels;
using SlamDunk.ValueObjects.Enums;

namespace SlamDunk.MES.Client.ViewModels.WorkOrderInspection
{
    /// <summary>
    /// 工序质量检查首页ViewModle
    /// </summary>
    public class IndexViewModel : ScreenBase, IPaginatable
    {
        #region # 字段及构造器
        /// <summary>
        /// 质量管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IQualityContract> _iQualityContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public IndexViewModel(ServiceProxy<IQualityContract> iQualityContract, IWindowManager windowManager)
        {
            this._iQualityContract = iQualityContract;
            this._windowManager = windowManager;

            //默认值
            this.PageIndex = 1;
            this.PageSize = 20;
        }

        #endregion

        #region # 属性

        #region 页码 —— int PageIndex
        /// <summary>
        /// 页码
        /// </summary>
        [DependencyProperty]
        public int PageIndex { get; set; }
        #endregion

        #region 页容量 —— int PageSize
        /// <summary>
        /// 页容量
        /// </summary>
        [DependencyProperty]
        public int PageSize { get; set; }
        #endregion

        #region 总记录数 —— int RowCount
        /// <summary>
        /// 总记录数
        /// </summary>
        [DependencyProperty]
        public int RowCount { get; set; }
        #endregion

        #region 总页数 —— int PageCount
        /// <summary>
        /// 总页数
        /// </summary>
        [DependencyProperty]
        public int PageCount { get; set; }
        #endregion

        #region 关键字
        /// <summary>
        /// 关键字
        /// </summary>
        [DependencyProperty]
        public string Keywords { get; set; }
        #endregion

        #region 审核状态列表
        /// <summary>
        /// 审核状态列表
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> CheckStatuss { get; set; }
        #endregion

        #region 开始时间
        /// <summary>
        /// 开始时间
        /// </summary>
        [DependencyProperty]
        public DateTime? StartTime { get; set; }
        #endregion

        #region 结束时间
        /// <summary>
        /// 结束时间
        /// </summary>
        [DependencyProperty]
        public DateTime? EndTime { get; set; }
        #endregion

        #region 已选审核状态列表
        /// <summary>
        /// 已选审核状态列表
        /// </summary>
        [DependencyProperty]
        public CheckStatus? SelectedCheckStatus { get; set; }
        #endregion

        #region 工序质量检查列表
        /// <summary>
        /// 工序质量检查列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<Wrap<WorkOrderInspectionInfo>> WorkOrderInspections { get; set; }
        #endregion
        #endregion

        #region # 方法

        #region 初始化 —— override async Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        protected override async Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            this.CheckStatuss = typeof(CheckStatus).GetEnumMembers();
            await this.ReloadWorkOrderInspections();
        }
        #endregion

        #region 创建 —— async void CreateWorkOrderInspect()
        /// <summary>
        /// 创建
        /// </summary>
        public async void CreateWorkOrderInspect()
        {
            AddViewModel viewModel = ResolveMediator.Resolve<AddViewModel>();
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                await this.ReloadWorkOrderInspections();
            }
        }
        #endregion

        #region 修改 —— async void UpdateWorkOrderInspect()
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name=""></param>
        public async void UpdateWorkOrderInspect()
        {
            #region # 验证
            WorkOrderInspectionInfo[] checkedRoles = this.WorkOrderInspections.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedRoles.Any() || checkedRoles.Count() != 1)
            {
                MessageBox.Show("请勾选一条工序质检！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (checkedRoles.FirstOrDefault().CheckStatus != CheckStatus.Unchecked && checkedRoles.FirstOrDefault().CheckStatus != CheckStatus.Rejected)
            {
                MessageBox.Show("当前工序质检不可修改！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            #endregion
            UpdateViewModel viewModel = ResolveMediator.Resolve<UpdateViewModel>();
            viewModel.Load(checkedRoles.FirstOrDefault());
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                await this.ReloadWorkOrderInspections();
            }
        }
        #endregion

        #region 查看 —— async void LookWorkOrderInspect()
        /// <summary>
        /// 查看
        /// </summary>
        /// <param name=""></param>
        public async void LookWorkOrderInspect()
        {
            #region # 验证
            WorkOrderInspectionInfo[] checkedRoles = this.WorkOrderInspections.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedRoles.Any() || checkedRoles.Count() != 1)
            {
                MessageBox.Show("请勾选一条工序质检！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            #endregion
            LookViewModel viewModel = ResolveMediator.Resolve<LookViewModel>();
            viewModel.Load(checkedRoles.FirstOrDefault());
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                await this.ReloadWorkOrderInspections();
            }
        }
        #endregion

        #region 删除 —— async void RemoveWorkOrderInspect()
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name=""></param>
        public async void RemoveWorkOrderInspect()
        {
            #region # 验证
            WorkOrderInspectionInfo[] checkedRoles = this.WorkOrderInspections.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedRoles.Any())
            {
                MessageBox.Show("请最少勾选一条工序质检！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            foreach (var item in checkedRoles)
            {
                if (item.CheckStatus != CheckStatus.Rejected && item.CheckStatus != CheckStatus.Unchecked)
                {
                    MessageBox.Show("当前勾选工序质检中存在审核中或审核完成单据！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            #endregion
            MessageBoxResult result = MessageBox.Show("确定要删除当前选中单据吗？", "提示", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if (result == MessageBoxResult.Yes)
            {
                foreach (var item in checkedRoles)
                {
                    await Task.Run(() => this._iQualityContract.Channel.RemoveQualityInspection(item.Id));
                }
                await this.ReloadWorkOrderInspections();
            }
        }
        #endregion

        #region 提交审核 —— async void SubmitWorkOrderInspect()
        /// <summary>
        /// 提交审核
        /// </summary>
        /// <param name=""></param>
        public async void SubmitWorkOrderInspect()
        {
            #region # 验证
            WorkOrderInspectionInfo[] checkedRoles = this.WorkOrderInspections.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedRoles.Any())
            {
                MessageBox.Show("请最少勾选一条工序质检！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            foreach (var item in checkedRoles)
            {
                if (item.CheckStatus != CheckStatus.Unchecked && item.CheckStatus != CheckStatus.Rejected)
                {
                    MessageBox.Show("当前勾选工序质检中存在已提交审核或审核完成单据！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }
            }
            #endregion
            MessageBoxResult result = MessageBox.Show("确定要提交审核当前选中单据吗？", "提示", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if (result == MessageBoxResult.Yes)
            {
                foreach (var item in checkedRoles)
                {
                    await Task.Run(() => this._iQualityContract.Channel.SubmitQualityInspection(item.Id));
                }
                await this.ReloadWorkOrderInspections();
            }
        }
        #endregion

        #region 审核 —— async void ExamineWorkOrderInspect()
        /// <summary>
        /// 审核
        /// </summary>
        /// <param name=""></param>
        public async void ExamineWorkOrderInspect()
        {
            #region # 验证
            WorkOrderInspectionInfo[] checkedRoles = this.WorkOrderInspections.Where(x => x.IsChecked == true).Select(x => x.Model).ToArray();
            if (!checkedRoles.Any() || checkedRoles.Count() != 1)
            {
                MessageBox.Show("请勾选一条工序质检！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            if (checkedRoles.FirstOrDefault().CheckStatus != CheckStatus.Checking)
            {
                MessageBox.Show("当前勾选工序质检必须是审核中状态单据！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            #endregion
            CheckViewModel viewModel = ResolveMediator.Resolve<CheckViewModel>();
            viewModel.Load(checkedRoles.FirstOrDefault());
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            if (result == true)
            {
                await this.ReloadWorkOrderInspections();
            }
        }
        #endregion

        #region 全选 —— void CheckAll()
        /// <summary>
        /// 全选
        /// </summary>
        public void CheckAll()
        {
            this.WorkOrderInspections.ForEach(x => x.IsChecked = true);
        }
        #endregion

        #region 取消全选 —— void UncheckAll()
        /// <summary>
        /// 取消全选
        /// </summary>
        public void UncheckAll()
        {
            this.WorkOrderInspections.ForEach(x => x.IsChecked = false);
        }
        #endregion

        #region 加载工序质量检查 —— async void LoadWorkOrderInspections()
        /// <summary>
        /// 加载工序质量检查
        /// </summary>
        public async void LoadWorkOrderInspections()
        {
            await this.ReloadWorkOrderInspections();
        }
        #endregion

        #region 打印 —— async void Print()
        /// <summary>
        /// 打印
        /// </summary>
        /// <param name=""></param>
        public async void Print()
        {
            #region # 验证
            if (this.WorkOrderInspections.Count(x => x.IsChecked == true) != 1)
            {
                MessageBox.Show("请勾选一条要打印的工序质检！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            #endregion
            Wrap<WorkOrderInspectionInfo> workOrderInspection = this.WorkOrderInspections.Single(x => x.IsChecked == true);

            this.Busy();
            IEnumerable<QualityInspectionDetailInfo> qualityInspectionDetails = await Task.Run(() => this._iQualityContract.Channel.GetQualityInspectionDetails(workOrderInspection.Model.Id));

            PrintViewModel viewModel = ResolveMediator.Resolve<PrintViewModel>();
            viewModel.Load(workOrderInspection.Model, qualityInspectionDetails);
            await this._windowManager.ShowDialogAsync(viewModel);
            this.Idle();
        }
        #endregion

        #region 导出
        /// <summary>
        /// 导出
        /// </summary>
        public async void Export()
        {
            PageModel<WorkOrderInspectionInfo> pageModel = await Task.Run(() => this._iQualityContract.Channel.GetWorkOrderInspectionsByPage(
                   this.Keywords,//关键字
                   null,
                   null,//工单Id
                   this.SelectedCheckStatus, //审核状态
                   this.StartTime,//开始时间
                   this.EndTime, //结束时间
                   this.PageIndex,//页码
                   this.PageSize));


            WorkOrderInspectionEm[] workOrderInspectionEms = pageModel.Datas.Select(x => x.ToExportView()).ToArray();
            if (!workOrderInspectionEms.Any())
            {
                MessageBox.Show("导出数据为空，不能进行导出！", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Filter = Constants.ExeclFileExtensionsFilter,
                FileName = $"工序质检_{DateTime.Now.ToString(Constants.ExportFileTimeFormat)}",
                AddExtension = true,
                RestoreDirectory = true
            };
            if (saveFileDialog.ShowDialog() == true)
            {
                string filePath = saveFileDialog.FileName;
                ExcelWriter.WriteFile(workOrderInspectionEms, filePath);
            }
        }
        #endregion


        //Private
        #region 加载工序质量检查 —— async Task ReloadWorkOrderInspections()
        /// <summary>
        /// 加载工序质量检查
        /// </summary>
        private async Task ReloadWorkOrderInspections()
        {
            this.Busy();

            PageModel<WorkOrderInspectionInfo> pageModel = await Task.Run(() => this._iQualityContract.Channel.GetWorkOrderInspectionsByPage(
                this.Keywords,//关键字
                null,//作业计划Id
                null,//工单Id
                this.SelectedCheckStatus, //审核状态
                this.StartTime,//开始时间
                this.EndTime, //结束时间
                this.PageIndex,//页码
                this.PageSize));
            this.RowCount = pageModel.RowCount;
            this.PageCount = pageModel.PageCount;

            IEnumerable<Wrap<WorkOrderInspectionInfo>> wrapModels = pageModel.Datas.Select(x => x.Wrap());
            this.WorkOrderInspections = new ObservableCollection<Wrap<WorkOrderInspectionInfo>>(wrapModels);

            this.Idle();
        }
        #endregion

        #endregion
    }
}
